package kontrolno2;

import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class CardNumbers {

	private static final int MAX_NUMBERS = 50;
	private static final int MIN_LENGTH = 6;
	private String[] cardNumbers;
	private int currentNumbers;

	public CardNumbers() {
		this.cardNumbers = new String[MAX_NUMBERS];
		this.currentNumbers = 0;
	}

	public void trim() {
		Set<String> uniqueNumbers = new HashSet<String>();
		for (int i = 0; i < currentNumbers; i++) {
			uniqueNumbers.add(cardNumbers[i]);
		}
		this.cardNumbers = new String[MAX_NUMBERS];
		this.currentNumbers = 0;
		for (String e : uniqueNumbers) {
			if (e != null)
				addCardNumbers(e);
		}
	}

	public void sort() {
		Arrays.sort(cardNumbers, 0, currentNumbers);
	}

	public void email(String to) throws MessagingException {
		// http://www.tutorialspoint.com/java/java_sending_email.htm
		// Couldn't do it without password, so mad a new gmail account
		String from = "ivanraychevtest@gmail.com";
		String password = "fuckingpassword";
		Properties props = System.getProperties();
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.auth", "true");
		props.put("mail.debug", "false");
		props.put("mail.smtp.ssl.enable", "true");
		Session session = Session.getInstance(props,
				(Authenticator) new GMailAuthenticator(from, password));

		try {
			MimeMessage message = new MimeMessage(session);
			message.setFrom(new InternetAddress(from));
			message.addRecipient(Message.RecipientType.TO, new InternetAddress(
					to));
			message.setSubject("Fake credit card numbers.");
			message.setText(toString());
			Transport.send(message);
		} catch (MessagingException mex) {
			throw new MessagingException("Error sending message", mex);
		}
	}

	public void addCardNumbers(String cardNumber)
			throws InvalidParameterException, ArrayStoreException {
		if (currentNumbers == MAX_NUMBERS)
			throw new ArrayStoreException("Array full");
		boolean valid = true;
		if (cardNumber.length() < MIN_LENGTH)
			valid = false;
		else
			for (int j = 0; j < cardNumber.length(); j++) {
				char a = cardNumber.charAt(j);
				if (!((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z') || (a >= '0' && a <= '9'))) {
					valid = false;
					break;
				}
			}
		if (valid) {
			this.cardNumbers[currentNumbers] = cardNumber;
			currentNumbers++;
		} else {
			throw new InvalidParameterException("Invalid card number.");
		}
	}

	public String getMostCommonNumber() {
		Map<String, Integer> numbers = new HashMap<String, Integer>();
		for (int i = 0; i < currentNumbers; i++) {
			String number = cardNumbers[i];
			if (numbers.containsKey(number))
				numbers.put(number, (numbers.get(number) + 1));
			else
				numbers.put(number, 1);
		}
		int max = Integer.MIN_VALUE;
		String key = "";
		for (String k : numbers.keySet()) {
			if (numbers.get(k) > max) {
				max = numbers.get(k);
				key = k;
			}
		}
		return key;
	}

	@Override
	public String toString() {
		String string = "[";
		for (int i = 0; i < currentNumbers; i++) {
			string += cardNumbers[i] + ", ";
		}
		string += "]";
		return string;
	}
}